package com.cet.qz.unit01.chapter1_1;

import edu.princeton.cs.algs4.StdRandom;

import java.security.InvalidParameterException;

/**
 * @program: algorithm
 * @description:
 * @author: 陈恩涛
 * @create: 2020-12-23 21:06
 **/
public class Exec01 {

    /*
     *方法描述： 掷骰子两次之和的概率分布,下标对应和
     *
     * @param
     * @return double[]
     * @author chenentao
     * @date 2020/12/23 21:14
     */
    public static double[] distribution(){

        int SIDES = 6;
        double[] distr = new double[2 * SIDES + 1];
        for (int i = 1; i <= 6; i++) {
            for (int j = 1; j <= 6; j++) {
                distr[i+j] += 1.0;
            }
        }
        for (int i = 2; i < distr.length; i++) {
            distr[i] /= 36;
        }

        return distr;
    }

    /*
     *方法描述： 模拟一次掷骰子
     *
     * @param
     * @return int
     * @author chenentao
     * @date 2020/12/23 21:18
     */
    public static int randomExec(){
        return StdRandom.uniform(6) + 1;
    }

    /*
     *方法描述： 模拟一次掷两个骰子，得到和
     *
     * @param
     * @return int
     * @author chenentao
     * @date 2020/12/23 21:22
     */
    public static int randomDoubleExec(){
        int e1 = randomExec();
        int e2 = randomExec();
        return e1 + e2;
    }

    /*
     *方法描述： N次实验，使连个骰子之和出现某个数的频率逼近对应概率，精确到小数点后三位
     *
     * @param n
     * @return int
     * @author chenentao
     * @date 2020/12/23 21:49
     */
    public static int randomDoubleNExec(int n){
        if(n < 2 || n >12)
            throw new InvalidParameterException("参数n为两个骰子之和，必须保证在2到12范围之内！");

        int count = 0;  //出现指定结果的次数
        int N = 1; //实验次数
        while ((int)(1000.0*count/N) != (int) (1000*distribution()[n])) {
            N++;
            int i = randomDoubleExec();
            if(i == n)
                count++;
            System.out.println(i + "\t "+1.0 * count / N);
        }
        return N;
    }

    public static void main(String[] args) {
        int n = 4;
        int N = randomDoubleNExec(n);
        System.out.println(N +"\t" + distribution()[n]);
    }
}
